/*
 * Copyright (C), 2005-2018, 上海瑛麒动漫科技有限公司
 * FileName: RepeatedlyReadRequestWrapper.java
 * Author:   tianmu
 * Date:     2018年3月1日 下午3:29:29
 * Description: //模块目的、功能描述
 * History: //修改记录
 * <author>      <time>      <version>    <desc>
 * 修改人姓名             修改时间            版本号                  描述
 */
package com.sfang.common.util.wrapper;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;

/**
 * 解决重复读取POST的body问题<br>
 * 〈功能详细描述〉
 *
 * @author tianmu
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
public class RepeatReadRequestWrapper extends HttpServletRequestWrapper {

    private byte[] body;

    public RepeatReadRequestWrapper(HttpServletRequest request) {
        super(request);

        try (InputStream in = request.getInputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();) {
            byte[] buf = new byte[1024];
            int read;
            while ((read = in.read(buf)) > 0) {
                baos.write(buf, 0, read);
            }
            this.body = baos.toByteArray();
        } catch (IOException e) {
            throw new RequestWrapperException(e);
        }
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream bais = new ByteArrayInputStream(body);

        return new ServletInputStream() {

            @Override
            public int read() {
                return bais.read();
            }

            @Override
            public boolean isFinished() {
                return bais.available() == 0;
            }

            @Override
            public boolean isReady() {
                return true;
            }

            @Override
            public void setReadListener(ReadListener readListener) {
                throw new UnsupportedOperationException();
            }
        };

    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

}
